package web.stu.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import web.stu.common.ErrorCode;
import web.stu.exception.BusinessException;
import web.stu.mapper.ScoreAuditMapper;
import web.stu.model.dto.scoreAudit.AddScoreAuditDTO;
import web.stu.model.dto.scoreAudit.QueryScoreAuditDTO;
import web.stu.model.entity.Score;
import web.stu.model.entity.ScoreAudit;
import web.stu.model.entity.User;
import web.stu.model.enums.ScoreAuditEnum;
import web.stu.model.vo.ScoreAuditVO;
import web.stu.model.vo.ScoreVO;
import web.stu.service.ScoreAuditService;
import web.stu.service.ScoreService;
import web.stu.service.UserService;

import javax.annotation.Resource;
import javax.servlet.Servlet;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author administer
 * @description 针对表【score_audit(成绩审核记录表)】的数据库操作Service实现
 * @createDate 2025-05-13 19:55:19
 */
@Slf4j
@Service
public class ScoreAuditServiceImpl extends ServiceImpl<ScoreAuditMapper, ScoreAudit>
        implements ScoreAuditService {
    @Resource
    private ScoreService scoreService;

    @Resource
    private UserService userService;
    @Autowired
    private Servlet servlet;

    @Override
    public void addAuditScore(AddScoreAuditDTO addScoreAuditDTO, HttpServletRequest request) {
        // 非空判断
        if (addScoreAuditDTO == null || addScoreAuditDTO.getScoreId() == null) {
            throw new BusinessException(ErrorCode.PRIMARY_ERROR);
        }
        // 获取原成绩记录
        Score score = scoreService.getById(addScoreAuditDTO.getScoreId());
        if (score == null) {
            throw new BusinessException(ErrorCode.PRIMARY_ERROR, "成绩记录不存在");
        }

        // 检查是否已存在相同的 scoreId
        ScoreAudit existingAudit = this.getOne(new QueryWrapper<ScoreAudit>().eq("score_id", addScoreAuditDTO.getScoreId()));
        if (existingAudit != null) {
            throw new BusinessException(ErrorCode.PRIMARY_ERROR, "该成绩记录已经存在审核记录");
        }

        // 校验新成绩是否合法
        if (addScoreAuditDTO.getNewScore() != null) {
            if (addScoreAuditDTO.getNewScore().compareTo(BigDecimal.ZERO) < 0 ||
                    addScoreAuditDTO.getNewScore().compareTo(new BigDecimal("100")) > 0) {
                throw new BusinessException(ErrorCode.PRIMARY_ERROR, "成绩必须在0-100之间");
            }
        }

        // 创建审核记录实体
        ScoreAudit newAudit = new ScoreAudit();
        newAudit.setScoreId(score.getId());
        newAudit.setAdminId(userService.getLoginUser(request).getId()); // 获取当前管理员ID
        newAudit.setOldScore(score.getScore());
        if (addScoreAuditDTO.getNewScore() != null) {
            newAudit.setNewScore(addScoreAuditDTO.getNewScore());
        }
        if (addScoreAuditDTO.getReason() != null) {
            newAudit.setReason(addScoreAuditDTO.getReason());
        }

        // 添加记录
        boolean res = this.save(newAudit);
        if (!res) {
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "添加成绩审核记录失败");
        }
    }

    @Override
    public Page<ScoreAuditVO> pageAuditRecords(QueryScoreAuditDTO queryScoreAuditDTO, HttpServletRequest request) {
        // 非空判断
        if (queryScoreAuditDTO == null) {
            throw new BusinessException(ErrorCode.PRIMARY_ERROR);
        }

        // 提取变量
        long current = queryScoreAuditDTO.getCurrent();
        long pageSize = queryScoreAuditDTO.getPageSize();
        // 分页查询
        Page<ScoreAudit> page = this.page(new Page<>(current, pageSize), this.getQueryWrapper(queryScoreAuditDTO));
        Page<ScoreAuditVO> scoreAuditVOPage = new Page<>(page.getCurrent(), page.getSize(), page.getTotal());

        // 获取ids
        Set<Integer> Ids = page.getRecords().stream().map(ScoreAudit::getScoreId).collect(Collectors.toSet());
        // 根据ids获取实体类
        Map<Integer, List<Score>> idScoreMap = scoreService.listByIds(Ids).stream().collect(Collectors.groupingBy(Score::getId));

        List<ScoreAuditVO> ScoreAuditVOList = page.getRecords().stream().map(scoreAudit -> {
            ScoreAuditVO scoreAuditVO = ScoreAuditVO.objToVO(scoreAudit);
            // 从内存中映射实体类拼接到返回对象中
            if (idScoreMap.containsKey(scoreAudit.getScoreId())) {
                Score score = idScoreMap.get(scoreAudit.getScoreId()).get(0);
                ScoreVO scoreVO = scoreService.getScoreById(score.getId());
                scoreAuditVO.setScoreVO(scoreVO);
                User auditer = userService.getById(scoreAudit.getScoreId());
                if (auditer != null) {
                    scoreAuditVO.setAuditName(auditer.getRealName());
                }
            }
            return scoreAuditVO;
        }).collect(Collectors.toList());
        scoreAuditVOPage.setRecords(ScoreAuditVOList);

        return scoreAuditVOPage;
    }

    @Override
    @Transactional
    public void updateAuditAndScore(AddScoreAuditDTO addScoreAuditDTO, HttpServletRequest request) {
        // 非空判断
        if (addScoreAuditDTO == null || addScoreAuditDTO.getScoreId() == null) {
            throw new BusinessException(ErrorCode.PRIMARY_ERROR);
        }

        // 查询审核记录
        ScoreAudit auditRecord = this.getById(addScoreAuditDTO.getId());
        if (auditRecord == null) {
            throw new BusinessException(ErrorCode.PRIMARY_ERROR, "审核记录不存在");
        }

        // 校验新成绩是否合法
        if (addScoreAuditDTO.getNewScore().compareTo(BigDecimal.ZERO) < 0 ||
                addScoreAuditDTO.getNewScore().compareTo(new BigDecimal("100")) > 0) {
            throw new BusinessException(ErrorCode.PRIMARY_ERROR, "成绩必须在0-100之间");
        }

        // 更新审核记录字段
        auditRecord.setNewScore(addScoreAuditDTO.getNewScore());
        auditRecord.setReason(addScoreAuditDTO.getReason());
        auditRecord.setAuditStatus(addScoreAuditDTO.getAuditStatus()); // 审核通过状态码为1
        // 根据记录的updateTime为现在
        auditRecord.setUpdateTime(new Date());
        boolean res = this.updateById(auditRecord);
        if (!res) {
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "修改成绩审核记录失败");
        }

        // 如果审核通过 就更新对应的成绩表记录
        if (Objects.equals(auditRecord.getAuditStatus(), Objects.requireNonNull(ScoreAuditEnum.getEnumByValue(ScoreAuditEnum.NORMAL.getText())).getValue())) {

            Score score = scoreService.getById(auditRecord.getScoreId());
            if (score == null) {
                throw new BusinessException(ErrorCode.PRIMARY_ERROR, "对应成绩记录不存在");
            }
            // 单一修改 不受其他事务影响
            Score updateScore = new Score();
            updateScore.setId(score.getId());
            updateScore.setScore(addScoreAuditDTO.getNewScore());
            boolean updated = scoreService.updateById(updateScore);
            if (!updated) {
                throw new BusinessException(ErrorCode.SYSTEM_ERROR, "修改成绩记录失败");
            }
        }
    }

    private QueryWrapper<ScoreAudit> getQueryWrapper(QueryScoreAuditDTO queryScoreAuditDTO) {
        QueryWrapper<ScoreAudit> queryWrapper = new QueryWrapper<>();
        if (queryScoreAuditDTO == null) {
            throw new BusinessException(ErrorCode.PRIMARY_ERROR);
        }

        // 提取变量
        Integer id = queryScoreAuditDTO.getId();
        Integer scoreId = queryScoreAuditDTO.getScoreId();
        Integer auditStatus = queryScoreAuditDTO.getAuditStatus();
        String reason = queryScoreAuditDTO.getReason();

        queryWrapper.eq(id != null, "id", id);
        queryWrapper.eq(scoreId != null, "score_id", scoreId);
        queryWrapper.eq(auditStatus != null, "audit_status", auditStatus);
        queryWrapper.like(reason != null, "reason", reason);

        return queryWrapper;


    }


}




